package push

import (
	"fmt"
	"github.com/labstack/echo"
	"log"
	. "mlgmd.com/hearsay/base"
	"mlgmd.com/hearsay/entities"
	"sync"
	"time"
)

//var listeners = map[int]func(event string, data string) error

var listeners = &sync.Map{} // key int 用户id value func(event string, data string) error{}

func HandlerRegister(UserId func(ctx echo.Context) int) func(ctx echo.Context) error {
	return func(ctx echo.Context) error {
		header := ctx.Response().Header()
		header.Set("Content-Type", "text/event-stream")
		header.Set("Cache-Control", "no-cache")
		header.Set("Connection", "keep-alive")
		header.Set("Access-Control-Allow-Origin", "*")
		listeners.Store(UserId(ctx), func(event string, data string) error {
			if _, err := ctx.Response().Write([]byte("event:" + event + "\ndata:" + data + "\n\n")); err != nil {
				listeners.Delete(UserId(ctx))
				log.Println("事件发送失败", err)
			}
			ctx.Response().Flush()
			return nil
		})
		if _, err := ctx.Response().Write([]byte("event:conn\ndata:ok\n\n")); err != nil {
			listeners.Delete(UserId(ctx))
			log.Println("事件发送失败", err)
		}
		ctx.Response().Flush()
		<-ctx.Response().CloseNotify()
		listeners.Delete(UserId(ctx))
		return nil
	}
}

func UserListener(uid int) (func(event string, data string) error, error) {
	listener, has := listeners.Load(uid) //listeners[uid]
	if !has {
		return nil, fmt.Errorf("用户不在线")
	}
	return listener.(func(event string, data string) error), nil
}

// Send 发送消息并推送
func Send(from, to int, content string, referType string, referId int, push bool) (err error) {
	defer Error(&err)
	Must2(DB.Insert(&entities.Message{
		CreatedTime: time.Now().Unix(),
		FromUserId:  from,
		ToUserId:    to,
		Content:     content,
		ReferType:   referType,
		ReferId:     referId,
	}))
	if push {
		log.Println("推送消息:", to, content)
		if lis, err := UserListener(to); err == nil {
			go func() {
				if err := lis("message", content); err != nil {
					log.Println("推送消息提醒失败")
				}
				log.Println("推送消息提醒成功")
			}()
		} else {
			log.Println("获取用户连接失败")
		}
	}
	return
}

func Save() {

}

func Push() {

}
